#include <unistd.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <stdio.h>
#include <pthread.h>
#include <string.h>

#define PORT 8888
#define NUM 2

void* ftn(void* arg)
{
	int cli_socket = (int)arg;
	
	char buf[BUFSIZ];

	write(cli_socket, "hello Mr.Xiong!\n", sizeof("hello Mr.Xiong!\n"));
	while(1)
	{
		write(cli_socket, "Me:", sizeof("Me:"));
		int ret = read(cli_socket, buf, sizeof(buf));
		
		if(ret == 0)
		{
			printf("a socket is closed");
			return NULL;
		}

		//write(cli_socket, "message has sent! wait for reply...\n", sizeof("message has sent! wait for reply...\n"));
		write(STDOUT_FILENO, "\nXJY:", sizeof("\nXJY:"));
		write(STDOUT_FILENO, buf, ret);
	}
	pthread_exit(NULL);
}

void* server(void* arg)
{
	int cli_socket = (int)arg;

	char buf[BUFSIZ];
	while(1)
	{
		write(STDOUT_FILENO, "Me:", sizeof("Me:"));
		int ret = read(STDIN_FILENO, buf, sizeof(buf));
		
		if(ret == 0)
		{
			printf("read nothing");
			return NULL;
		}

		//write(cli_socket, "message has sent! wait for reply...\n", sizeof("message has sent! wait for reply...\n"));
		write(cli_socket, "\nTK:", sizeof("\nTK"));
		write(cli_socket, buf, ret);
	}
	pthread_exit(NULL);
}

int main(int argc, char** argv)
{
	int serv_socket, cli_socket;
	//int vector[NUM];
	//int i = 0;
	struct sockaddr_in serv_addr, cli_addr;
	socklen_t cli_socklen = sizeof(cli_addr);

	serv_socket = socket(AF_INET, SOCK_STREAM, 0);
	
	memset(&serv_addr, 0, sizeof(serv_addr));
	serv_addr.sin_family = AF_INET;
	serv_addr.sin_port = htons(PORT);
	serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);

	int opt = 1;
	setsockopt(serv_socket, SOL_SOCKET, SO_REUSEADDR, (void*)&opt, sizeof(opt));

	if(bind(serv_socket, (struct sockaddr*)&serv_addr, sizeof(serv_addr))<0)perror("bind:");

	listen(serv_socket, NUM);//invalid to set backlog

	pthread_t thread;
	pthread_attr_t attr;
	pthread_attr_init(&attr);
	pthread_attr_setdetachstate(&attr,PTHREAD_CREATE_DETACHED);


	while(1)
	{
		cli_socket = accept(serv_socket, (struct sockaddr*)&cli_addr, &cli_socklen);
		
		//printf("i = %d\n", i);	

		//vector[i] = cli_socket;		

		pthread_create(&thread,&attr,ftn,(void*)cli_socket);
		pthread_create(&thread,&attr,server,(void*)cli_socket);
		//i = (i+1)%NUM;
	}
	pthread_attr_destroy(&attr);
	pthread_exit(NULL);	
}
